/**
 * API 通用类
 * @author rxliuli
 */
/**
 * 后端查询结果封装类
 */
class Result {
    /**
     * 构造函数
     * @param {Object} option 可选项
     * @param {Number} [option.code] 返回代码
     * @param {String} [option.msg] 错误消息
     * @param {Object} [option.data] 返回数据
     */
    constructor({
                    code,
                    msg,
                    data,
                }) {
        this.code = code
        this.msg = msg
        this.data = data
    }
}

/**
 * 基本的 api 基类
 */
class BaseApi {
    /**
     * 子类必须重写该属性
     * @param url 基本的 url 列表
     * @param exp 是否包含通用的导出
     * @param imp 是否包含通用的导入
     */
    constructor({url, exp = false, imp = false} = {}) {
        if (arguments.length < 1) {
            throw new Error('必须至少提供一个 url 参数')
        }
        let arg = arguments[0]
        if (arguments.length >= 1 && typeof arg === 'string') {
            this.url = arg
            return
        }
        if (arg.exp === true) {
            Object.assign(this, {
                exportFile: async form => {
                    const res = await rxajax.get(this.using('/export-data'), form, {
                        responseType: 'blob',
                    })
                    return new Blob(
                        [res.data],
                        {
                            type: res.headers['content-type'],
                        },
                    )
                },
            })
        }
        if (arg.imp === true) {
            Object.assign(this, {
                importFile: async (file) => {
                    const res = await rxajax.post(this.using('/import-data'), {file}, {
                        responseType: 'blob',
                    })
                    if (parseInt(res.headers['content-length']) === 0) {
                        return
                    }
                    return new Blob([res.data], {
                        type: res.headers['content-type'],
                    })
                },
                downloadTemplate: async (fileName) => {
                    const res = await rxajax.get(this.using('/download-template'), {}, {
                        responseType: 'blob',
                    })
                    rx.download(
                        new Blob([res.data], {
                            type: res.headers['content-type'],
                        }),
                        fileName,
                    )

                },
            })
        }
        this.url = arg.url
    }

    /**
     * 使用该方法将 url 转换为全路径的 url
     * @param url 相对路径
     * @returns {string} 绝对路径的 url
     */
    using(url = '') {
        return rx.pathUtil.join(this.url, url)
    }

    /**
     * 通用的根据 id 查询
     * @param id 主键
     * @returns {Promise<void>} 查询到的对象
     */
    async get(id) {
        return (await rxajax.get(this.using(`/get/${id}`))).data.data
    }

    /**
     * 通用的分页查询函数
     * 注：必须保证服务端的分页也是这样的
     * @param page 分页信息
     * @param entity 实体类
     * @returns {Promise<Page>} 分页数据
     */
    async page(page, entity) {
        return await rxajax.page(this.using('/query-page'), page, entity)
    }

    /**
     * 通用的查询下拉框列表
     * @returns {Promise.<Array.<BaseHouseInfo>>} 下拉框列表
     */
    async selectList() {
        return (await rxajax.get(this.using('/select-list'))).data.data
    }

    /**
     *通用的查询下拉框列表 带参数
     * @param entity
     * @returns {Promise<*>}
     */
    async selectListByParam(entity) {
        return (await rxajax.post(this.using('/select-list-param'), entity, {type: 'json'})).data.data
    }

    /**
     * 通用的添加函数
     * 注：必须保证服务端的添加也是这样的
     *
     * @param entity 添加的对象
     * @returns {Promise<Result>} 结果
     */
    async add(entity) {
        return (await rxajax.post(this.using('/add'), entity, {
            type: 'json',
        })).data
    }

    /**
     * 通用的更新函数
     * @param entity 更新的对象
     * @returns {Promise<Result>} 结果
     */
    async update(entity) {
        return (await rxajax.post(this.using('/update'), entity, {
            type: 'json',
        })).data
    }

    /**
     * 根据 id 删除
     * @param id id
     * @returns {Promise<Result>} 删除结果
     */
    async delete(id) {
        return (await rxajax.post(this.using(`/delete/${id}`))).data
    }

    /**
     * 批量删除
     * @param idList id 列表
     * @returns {Promise<Result>} 批量删除结果
     */
    async deleteBatch(idList) {
        return (await rxajax.post(this.using('/delete/batch'), idList, {
            type: 'json',
        })).data
    }

    /**
     * 通用的统计总数
     * @returns {Promise.<Array.<BaseHouseInfo>>} 下拉框列表
     */
    async total(entity) {
        return (await rxajax.get(this.using('/total'), entity)).data.data
    }
}
